

#include "unity.h"
#include "unity_fixture.h"

#include <ICC/Connector.h>
#include <ICC/Slot.h>

#include "Debug.h"
#include "BSP_Sleep.h"

#include <HID/command.h>
#include <HID/HIDiClass.h>
#include <HID/ipcMessage.h>
#include <HID/HidRF.h>
#include <HID/asn1.h>

#include <Reader/Reader.h>
#include <Reader/ReaderHidHF.h>

extern slot_t Slot[1];


TEST_GROUP(IClass);


TEST_SETUP(IClass)
{
	IClass_Init();
}

TEST_TEAR_DOWN(IClass)
{
	IClass_PowerOff();
}


TEST(IClass, SEPowerOn)
{
	uint8_t atr[32];
	uint8_t alen;
	int ret;
	for( int i = 0; i < 1000; i++){
		Connector_Init();
		CharacterModule_Init();
		Slot_Init();
		ret = Slot_PowerOn(Slot, atr, &alen);
		if(!ret){
			BSP_Sleep_Ms(10);
			Slot_PowerOff(Slot);
//				break;
		}
		BSP_Sleep_Ms(500);
	}
	TEST_ASSERT_EQUAL_INT_MESSAGE(0, ret, "PowerOn fail!");
	if(!ret){
		LOG_B("atr:", atr, alen, 8);
	}
}


IGNORE_TEST(IClass, SEGetVersion)
{
	int i;

	for(i = 0; i < 1000; i++){
		IClass_PowerOff();
		BSP_Sleep_Ms(500);
		int ret = IClass_PowerOn();
//			TEST_ASSERT_EQUAL_INT_MESSAGE(0, ret, "PowerOn fail!");
		uint8_t ver[64];
		uint8_t vlen;
		ret = IClass_GetSEVersion(ver, &vlen);
//			TEST_ASSERT_EQUAL_INT_MESSAGE(0, ret, "GetVersion fail!");
		if(!ret){
			LOG_B("ver:", ver, vlen, 8);
		}
	}

}
#if 0

#if 0
TEST(IClass, Find)
{
	int ret;
	uint8_t csn[64];
	for(int i = 0; i < 5; i++){
		BSP_Sleep_Ms(200);
		ret = IClass_PowerOn();
		if(ret){
			LOG_E("PowerOn fail: %d", ret);
		}
		else{
			ret = IClass_Find(csn);
			if(!ret){
				LOG_B("csn:", csn, 8, 8);
				break;
			}
		}
		IClass_PowerOff();
	}
}
#endif 

IGNORE_TEST(IClass, GetEelementContent)
{
	int ret;
	uint8_t buf[64];
	for(int i = 0; i < 10000; i++){
		BSP_Sleep_Ms(200);
		ret = IClass_PowerOn();
		if(ret){
			LOG_E("PowerOn fail: %d", ret);
		}
		else{
			ret = IClass_Find(buf);
			if(!ret){
				LOG_B("csn:", buf, 8, 8);
				uint8_t len = 0;
				ret = IClass_GetEelementContent(buf, &len);
				if(!ret){
					LOG_B("content:", buf, len, 16);
				}
			}
		}
		IClass_PowerOff();
	}
}


IGNORE_TEST(IClass, GetEelementContent2)
{
	int ret;
	uint8_t buf[64];
	SimpleTag_T info;
	uint8_t* resp;
	uint8_t rlen;
	reader.hfFlags = TAG_MASK_HIDICLASS;
	Reader_NFC_LoadProfile(TAG_MASK_HIDICLASS, 0, 0, 0);
	for(int i = 0; i < 10000; i++){
		IClass_PowerOff();
		BSP_Sleep_Ms(200);
		ret = Reader_NFC_Discovery(&info);
		if(ret){
			continue;
		}
		HID_RF_SetFeild(0);
		BSP_Sleep_Ms(100);
//			HID_RF_SetFeild(1);
//			HID_RF_Init();
//			ret = IClass_PowerOnSE();
		ret = IClass_PowerOn();
		if(ret){
			LOG_E("PowerOn fail: %d", ret);
			continue;
		}
		rlen = 0;
		//ret = SamCommand_SetDetectedCardInfo(ASN1_FRAME_PROTOCOL_PICO15693, info.uid, info.ulen, NULL, 0, NULL, buf, &rlen);
		ret = SamCommand_PerformAnticollision(ASN1_FRAME_PROTOCOL_PICO15693, buf, &rlen);
		if(ret){
			LOG_E("SamCommand_PerformAnticollision fail: %d", ret);
			continue;
		}
		resp = NULL;
		ret = SamCommand_GetContentElement2(&resp, &rlen);
		if(ret){
			LOG_E("SamCommand_GetContentElement2 fail: %d", ret);
			continue;
		}
		const uint8_t tag = ASN1_CHOICE_PRIMITIVE|0;
		ret = IClass_ExtractData(resp, rlen, tag, buf, &rlen);
		if(ret){
			LOG_E("IClass_ExtractData: %d", ret);
			continue;
		}
		LOG_B("content:", buf, rlen, 16);
	}
}

IGNORE_TEST(IClass, GetEelementContentA)
{
	int ret;
	uint8_t buf[64];
	SimpleTag_T info;
	uint8_t* resp;
	uint8_t rlen;
	
	reader.hfFlags = TAG_MASK_MIFARE;
	for(int i = 0; i < 10000; i++){
		IClass_PowerOff();
		BSP_Sleep_Ms(200);
		ret = Reader_NFC_Discovery(&info);
		if(ret){
			continue;
		}
//			HID_RF_SetFeild(0);
//			BSP_Sleep_Ms(100);
//			HID_RF_SetFeild(1);
		ret = IClass_PowerOnSE();
//			ret = IClass_PowerOn();
		if(ret){
			LOG_E("PowerOn fail: %d", ret);
			continue;
		}
		phacDiscLoop_Sw_DataParams_t *pDataParams = reader.pDiscLoop;
		//uint8_t * ats = pDataParams->sTypeATargetInfo.sTypeA_I3P4.pAts;
		uint8_t* uid = pDataParams->sTypeATargetInfo.aTypeA_I3P3[0].aUid;
		uint8_t ulen = pDataParams->sTypeATargetInfo.aTypeA_I3P3[0].bUidSize;
		uint8_t sak = pDataParams->sTypeATargetInfo.aTypeA_I3P3[0].aSak;
		//uint8_t atr[6] = {0x3B,0x81,0x80,0x01,0x80,0x80};
		//uint8_t atr[5] = {0x3B,0x80,0x80,0x01,0x01};
		uint8_t *ats = pDataParams->sTypeATargetInfo.sTypeA_I3P4.pAts;
		uint8_t tcl = 1;
		if((sak & 0x20) == 0){
			ats[0] = 0;
			tcl = 0;
		}
//			HID_RF_Init(ASN1_FRAME_PROTOCOL_ISO14443A, tcl);
		HID_RF_TransceiveSelect(tcl);
		rlen = 0;
		ret = SamCommand_SetDetectedCardInfo2(ASN1_FRAME_PROTOCOL_ISO14443A, uid, ulen, ats + 1, ats[0], &sak, NULL, &resp, &rlen);
//			ret = SamCommand_PerformAnticollision(ASN1_FRAME_PROTOCOL_PICO15693, buf, &rlen);
		if(ret){
			LOG_E("SamCommand_PerformAnticollision fail: %d", ret);
			continue;
		}
		resp = NULL;
		rlen = 0;
		ret = SamCommand_GetContentElement2(&resp, &rlen);
		if(ret){
			LOG_E("SamCommand_GetContentElement2 fail: %d", ret);
			continue;
		}
		const uint8_t tag = ASN1_CHOICE_PRIMITIVE|0;
		ret = IClass_ExtractData(resp, rlen, tag, buf, &rlen);
		if(ret){
			LOG_E("IClass_ExtractData: %d", ret);
			continue;
		}
		LOG_B("content:", buf, rlen, 16);
	}
}

TEST(IClass, GetPAC)
{
	int ret;
	uint8_t buf[64];
	SimpleTag_T info;
	uint8_t* resp;
	uint8_t rlen;
	
	reader.hfFlags = TAG_MASK_MIFARE | TAG_MASK_HIDICLASS;
	Reader_NFC_LoadProfile(reader.hfFlags, 0, 0, 0);
	for(int i = 0; i < 10000; i++){
		IClass_PowerOff();
		BSP_Sleep_Ms(500);
		ret = Reader_NFC_Discovery(&info);
		if(ret){
			continue;
		}
		if(info.type != HFTAG_HIDICLASS){
			continue;
		}
		ret = Reader_HID_HF_GetPACBits(buf, &rlen);
		if(ret){
			LOG_E("Reader_HID_HF_GetPACBits: %d", ret);
			continue;
		}
		LOG_B("content:", buf, rlen, 16);
	}
}

int Reader_HID_HF_PowerOnSE(void);

int Reader_HID_HF_SetupSE(void);

IGNORE_TEST(IClass, ReadBlock)
{
	int ret;
	uint8_t buf[64];
	SimpleTag_T info;
	uint8_t* resp;
	uint8_t rlen;
	
	reader.hfFlags = TAG_MASK_HIDICLASS;
	for(int i = 0; i < 10000; i++){
		IClass_PowerOff();
		BSP_Sleep_Ms(200);
		ret = Reader_NFC_Discovery(&info);
		if(ret){
			continue;
		}
		ret = Reader_HID_HF_PowerOnSE();
		if(ret){
			LOG_E("Reader_HID_HF_PowerOnSE: %d", ret);
			continue;
		}
		ret = Reader_HID_HF_SetupSE();
		if(ret){
			LOG_E("Reader_HID_HF_SetupSE: %d", ret);
			continue;
		}
		uint8_t book = 0;
		uint8_t page = 0;
		uint8_t config [16];
		ret = IClass_Select(book, page, config);
		if(ret){
			LOG_E("IClass_Select: %d", ret);
			continue;
		}
		uint8_t app = 0, oid[2] = {0x00, 0x23};
		ret = IClass_Auth(app, oid);
		if(ret){
			LOG_E("IClass_Auth: %d", ret);
			continue;
		}
		uint8_t block = 17;
		ret = IClass_Read(block, buf);
		if(ret){
			LOG_E("IClass_Read: %d", ret);
			continue;
		}
		LOG_B("content:", buf, 4, 16);
	}
}

#endif 


